require "prefabutil"

local assets =
{
    Asset("ANIM", "anim/tf_hot_pot_rack.zip"),
}

local prefabs =
{
    "collapse_small",
}


local TAGS = {
    "monster", "hostile", "scarytoprey", "canbetrapped", "smallcreature", "spider", "trader",
    "animal", "prey", "rabbit", "cattoy", "catfood", "cookable"
}

local function SetShow(inst, old_item, show, slot)
    -- 不显示时，移除已有对象
    if not show then
        if inst.show_item[slot] ~= nil then
            inst.show_item[slot]:Remove()
            inst.show_item[slot] = nil
        end
        return
    end

    -- 如果已经有相同的物品在显示，就不用重复生成
    if inst.show_item[slot] ~= nil and inst.show_item[slot].prefab == old_item.prefab then
        return
    end

    -- 清理旧物品
    if inst.show_item[slot] ~= nil then
        inst.show_item[slot]:Remove()
        inst.show_item[slot] = nil
    end

    -- 生成新的展示对象
    local prefab  = old_item.prefab
    local skin    = old_item.skinname
    local skin_id = old_item.skin_id
    local user    = old_item.userid

    -- 如果确实有皮肤名，则使用 4 个参数生成，否则只传入 prefab
    local item
    if skin ~= nil then
        item = SpawnPrefab(prefab, skin, skin_id, user)
    else
        item = SpawnPrefab(prefab)
    end
    if item == nil then
        return
    end

    -- 若没有 Follower 组件，则手动加
    if item.Follower == nil then
        item.entity:AddFollower()
    end
    item.entity:SetParent(inst.entity)

    -- 根据 slot 决定跟随的符号
    if slot == 1 then
        item.Follower:FollowSymbol(inst.GUID, "swap09", nil, nil, nil, true)
    elseif slot == 2 then
        item.Follower:FollowSymbol(inst.GUID, "swap08", nil, nil, nil, true)
    elseif slot == 3 then
        item.Follower:FollowSymbol(inst.GUID, "swap07", nil, nil, nil, true)
    elseif slot == 4 then
        item.Follower:FollowSymbol(inst.GUID, "swap06", nil, nil, nil, true)
    elseif slot == 5 then
        item.Follower:FollowSymbol(inst.GUID, "swap05", nil, nil, nil, true)
    elseif slot == 6 then
        item.Follower:FollowSymbol(inst.GUID, "swap04", nil, nil, nil, true)
    elseif slot == 7 then
        item.Follower:FollowSymbol(inst.GUID, "swap03", nil, nil, nil, true)
    elseif slot == 8 then
        item.Follower:FollowSymbol(inst.GUID, "swap02", nil, nil, nil, true)
    elseif slot == 9 then
        item.Follower:FollowSymbol(inst.GUID, "swap01", nil, nil, nil, true)
    end

    -- 去掉多余标签和逻辑（让它只是一个可见模型）
    for _, v in ipairs(TAGS) do
        item:RemoveTag(v)
    end
    item:AddTag("INLIMBO")
    item:AddTag("NOCLICK")
    item.inlimbo = true
    item:StopBrain()

    if item.Physics then
        item.Physics:SetActive(false)
    end
    if item.DynamicShadow then
        item.DynamicShadow:Enable(false)
    end
    if item.MiniMapEntity then
        item.MiniMapEntity:SetEnabled(false)
    end
    if item.components.health then
        item.components.health:SetInvincible(true)
    end
    if item.components.perishable then
        item.components.perishable:StopPerishing()
    end
    if item.components.edible then
        item:RemoveComponent("edible")
    end

    -- 不需要保存到存档
    item.persists = false

    -- 记录下来，方便后续移除
    inst.show_item[slot] = item
end

local function GetSlot(inst, slot)
    local item = inst.components.container.slots[slot]
    if item == nil then
        return
    end

    SetShow(inst, item, true, slot)
end

local function LoseSlot(inst, slot, prev_item)
    local item = inst.components.container.slots[slot]
    if item == nil then
        SetShow(inst, nil, false, slot)
    end
end

local function ItemGet_chest(inst, data)
    if data and data.slot then
        GetSlot(inst, data.slot)
    end
end
local function ItemLose_chest(inst, data)
    if data and data.slot then
        LoseSlot(inst, data.slot, data.prev_item)
    end
end

local function onopen(inst)
    inst.AnimState:PlayAnimation("open")
    inst.SoundEmitter:PlaySound("dontstarve/common/icebox_open")
end

local function onclose(inst)
    inst.AnimState:PlayAnimation("close")
    inst.AnimState:PushAnimation("idle", false)
    inst.SoundEmitter:PlaySound("dontstarve/common/icebox_close")
end

local function onhammered(inst, worker)
    inst.components.lootdropper:DropLoot()
    inst.components.container:DropEverything()
    local fx = SpawnPrefab("collapse_small")
    fx.Transform:SetPosition(inst.Transform:GetWorldPosition())
    fx:SetMaterial("metal")
    inst:Remove()
end

local function onhit(inst, worker)
    inst.AnimState:PlayAnimation("hit")
    inst.components.container:DropEverything()
    inst.AnimState:PushAnimation("idle", false)
    inst.components.container:Close()
end

local function onbuilt(inst)
    inst.AnimState:PlayAnimation("place")
    inst.AnimState:PushAnimation("idle", false)
    inst.SoundEmitter:PlaySound("dontstarve/common/icebox_craft")
end

local function SetPerishRate(inst, item)
    if item == nil then
        return TUNING.TICKF
    end
    if item:HasTag("frozen") and TUNING.TICKF > 0 then
        return 0
    end
    return TUNING.TICKF
end

local function fn()
    local inst = CreateEntity()

    inst.entity:AddTransform()
    inst.entity:AddAnimState()
    inst.entity:AddSoundEmitter()
    inst.entity:AddMiniMapEntity()
    inst.entity:AddNetwork()

    inst:SetDeploySmartRadius(0.75) -- recipe min_spacing/2

    inst.MiniMapEntity:SetIcon("tf_hot_pot_rack.tex")

    inst:AddTag("fridge")
    inst:AddTag("structure")

    inst.show_item = {}

    inst.AnimState:SetBank("tf_hot_pot_rack")
    inst.AnimState:SetBuild("tf_hot_pot_rack")
    inst.AnimState:PlayAnimation("idle")

    inst.entity:SetPristine()

    if not TheWorld.ismastersim then
        return inst
    end

    inst:AddComponent("inspectable")
    inst:AddComponent("container")
    inst.components.container:WidgetSetup("tf_hot_pot_rack")
    inst.components.container.onopenfn = onopen
    inst.components.container.onclosefn = onclose
    inst.components.container.skipclosesnd = true
    inst.components.container.skipopensnd = true
    inst.components.container:EnableInfiniteStackSize(true) -- 启用无限堆叠

    inst:AddComponent("preserver")
    inst.components.preserver:SetPerishRateMultiplier(SetPerishRate)


    inst:AddComponent("lootdropper")
    inst:AddComponent("workable")
    inst.components.workable:SetWorkAction(ACTIONS.HAMMER)
    inst.components.workable:SetWorkLeft(2)
    inst.components.workable:SetOnFinishCallback(onhammered)
    inst.components.workable:SetOnWorkCallback(onhit)

    inst:ListenForEvent("onbuilt", onbuilt)
    inst:ListenForEvent("itemget", ItemGet_chest)
    inst:ListenForEvent("itemlose", ItemLose_chest)

    AddHauntableDropItemOrWork(inst)

    return inst
end

return Prefab("tf_hot_pot_rack", fn, assets, prefabs),
    MakePlacer("tf_hot_pot_rack_placer", "tf_hot_pot_rack", "tf_hot_pot_rack", "idle")
